﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Linq.Expressions;
using System.Web.Routing;
using System.Text;
using System.IO;
using Utils;

namespace WebUI.HtmlHelpers
{
    public static class UrlHelpers
    {
        public static string StaticFile(this UrlHelper url, string staticFilePath, Boolean versioningOnly = false)
        {
            //if staticFilePath includes ? mark, then we get rid of that part first.
            int qIndex = staticFilePath.LastIndexOf("?");
            if (qIndex >= 0)
            {
                staticFilePath = staticFilePath.Substring(0, qIndex);
            }
            string absoluteFilePath = url.RequestContext.HttpContext.Server.MapPath(staticFilePath);
            //has performance issue? another solution is to cache fileinfo in GlobalUtilities, or cache here
            FileInfo fileInfo = new FileInfo(absoluteFilePath);
            TimeSpan span = fileInfo.LastWriteTime - new DateTime(2001, 1, 1);
            if (staticFilePath.StartsWith("~"))
            {
                staticFilePath = staticFilePath.Substring(1);
            }
            //if files are to be combined or it's a combined file, return what it is
            string finalPath = string.Empty;
            if (versioningOnly)
            {
                finalPath = staticFilePath;
            }
            else
            {
                string minFileNameTag = ".min";
                //string releaseFilePathPrefix = GlobalUtilities.GetInstance().MinificationFilePathPrefix; //do not use static path for minificaiton file
                //now minification file has same folder with the orginal file

                //if not combined, or to be combined, and need do minification
                if (GlobalUtilities.GetInstance().MinifyJsCssFiles)
                {
                    //staticFilePath:  /content/css/styles.css, or /content/scripts/jquery-1.7.1.min.js
                    int index1 = 0;
                    int index2 = staticFilePath.LastIndexOf('/');
                    int index3 = staticFilePath.LastIndexOf('\\');
                    index1 = Math.Max(index2, index3);
                    //get the name
                    string fileName = string.Empty;
                    string pathPrefix = string.Empty;
                    if (index1 >= 0)
                    {
                        fileName = staticFilePath.Substring(index1 + 1);
                        pathPrefix = staticFilePath.Substring(0, index1 + 1);
                    }
                    else
                    {
                        fileName = staticFilePath;
                        pathPrefix = string.Empty;
                    }

                    int innerIndex = fileName.LastIndexOf('.');
                    if (innerIndex >= 0)
                    {
                        //only ext
                        string ext = fileName.Substring(innerIndex + 1);
                        //only do minification on js and css files, 
                        if (ext.ToLower() != "js" && ext.ToLower() != "css")
                        {
                            finalPath = staticFilePath;
                        }
                        else
                        { 
                            //get name without ext
                            string name = fileName.Substring(0, innerIndex);
                            //if name includes .min, we don't add '.min'
                            if (name.ToLower().EndsWith(minFileNameTag))
                            {
                                finalPath = pathPrefix + name + "." + ext;
                            }
                            else
                            {
                                finalPath = pathPrefix + name + minFileNameTag + "." + ext;
                            }
                        }
                    }
                    else
                    {
                        finalPath = staticFilePath;
                    }
                }
                else
                {
                    finalPath = staticFilePath;
                }
            }
            return finalPath +"?v=" + Math.Round(span.TotalSeconds).ToString();
        }

        public static Uri GetBaseUrl(this UrlHelper url)
        {
            Uri contextUri = new Uri(url.RequestContext.HttpContext.Request.Url, url.RequestContext.HttpContext.Request.RawUrl);
            UriBuilder realmUri = new UriBuilder(contextUri) { Path = url.RequestContext.HttpContext.Request.ApplicationPath, Query = null, Fragment = null };
            return realmUri.Uri;
        }


        public static string StripProtocol(this string url)
        {
            return url.ToString().Replace("http://", "").Replace("https://", "");
        }


        public static string ActionAbsolute(this UrlHelper url, string actionName, string controllerName)
        {
            return ActionAbsolute(url, actionName, controllerName, null);
        }
        public static string ActionAbsolute(this UrlHelper url, string actionName, string controllerName, object routeValues)
        {
            return new Uri(GetBaseUrl(url), url.Action(actionName, controllerName, routeValues)).AbsoluteUri;
        }
    }

}
